<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Claude Code Workdir Monitor</title>
    <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
    <style>
        .status-active { @apply bg-red-100 text-red-800 border-red-200; }
        .status-active-text { color: #dc2626 !important; font-weight: bold; }
        .status-inactive { @apply bg-gray-100 text-gray-600 border-gray-200; }
        .card { @apply bg-white rounded-lg shadow-md p-6 transition-all duration-300 hover:shadow-lg; }
        .gradient-bg { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
        .workdir-card:hover { transform: translateY(-2px); }
        .search-highlight { background-color: yellow; }
        .loading { opacity: 0.6; pointer-events: none; }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Header -->
    <header class="gradient-bg text-white shadow-lg">
        <div class="container mx-auto px-6 py-4">
            <div class="flex items-center justify-between">
                <div class="flex items-center space-x-4">
                    <i class="fas fa-chart-line text-2xl"></i>
                    <h1 class="text-2xl font-bold">Claude Code Workdir Monitor</h1>
                </div>
                <div class="flex items-center space-x-4">
                    <div class="flex items-center space-x-2">
                        <div class="w-3 h-3 bg-green-400 rounded-full animate-pulse" id="connection-status"></div>
                        <span class="text-sm" id="connection-text">Connected</span>
                    </div>
                    <span class="text-sm opacity-80" id="last-updated">Loading...</span>
                </div>
            </div>
        </div>
    </header>

    <!-- Controls -->
    <div class="container mx-auto px-6 py-6">
        <div class="card mb-6">
            <div class="flex flex-wrap items-center justify-between gap-4">
                <div class="flex flex-wrap gap-4">
                    <!-- Search -->
                    <div class="flex items-center space-x-2">
                        <i class="fas fa-search text-gray-400"></i>
                        <input 
                            type="text" 
                            id="search-input" 
                            placeholder="Search workdirs..." 
                            class="border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
                        >
                    </div>
                    
                    <!-- Filters -->
                    <select id="filter-status" class="border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
                        <option value="all">All Status</option>
                        <option value="active">Active Only</option>
                        <option value="inactive">Inactive Only</option>
                    </select>
                    
                    <select id="filter-hours" class="border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
                        <option value="">All Time</option>
                        <option value="1">Last Hour</option>
                        <option value="6">Last 6 Hours</option>
                        <option value="24">Last 24 Hours</option>
                        <option value="168">Last Week</option>
                    </select>
                </div>
                
                <div class="flex items-center space-x-4">
                    <!-- Sort -->
                    <select id="sort-by" class="border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500">
                        <option value="last_activity">Last Activity</option>
                        <option value="total_tokens">Total Tokens</option>
                        <option value="total_cost">Total Cost</option>
                        <option value="session_count">Session Count</option>
                        <option value="workdir">Directory Name</option>
                    </select>
                    
                    <!-- Refresh -->
                    <button id="refresh-btn" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg transition-colors duration-200">
                        <i class="fas fa-sync-alt mr-2"></i>Refresh
                    </button>
                </div>
            </div>
        </div>

        <!-- Summary Cards -->
        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
            <div class="card">
                <div class="flex items-center justify-between">
                    <div>
                        <p class="text-gray-600 text-sm">Total Workdirs</p>
                        <p class="text-3xl font-bold text-gray-800" id="total-workdirs">-</p>
                    </div>
                    <div class="bg-blue-100 p-3 rounded-full">
                        <i class="fas fa-folder text-blue-500 text-xl"></i>
                    </div>
                </div>
            </div>
            
            <div class="card">
                <div class="flex items-center justify-between">
                    <div>
                        <p class="text-gray-600 text-sm">Active Workdirs</p>
                        <p class="text-3xl font-bold text-green-600" id="active-workdirs">-</p>
                    </div>
                    <div class="bg-green-100 p-3 rounded-full">
                        <i class="fas fa-play-circle text-green-500 text-xl"></i>
                    </div>
                </div>
            </div>
            
            <div class="card">
                <div class="flex items-center justify-between">
                    <div>
                        <p class="text-gray-600 text-sm">Total Tokens</p>
                        <p class="text-3xl font-bold text-purple-600" id="total-tokens">-</p>
                    </div>
                    <div class="bg-purple-100 p-3 rounded-full">
                        <i class="fas fa-coins text-purple-500 text-xl"></i>
                    </div>
                </div>
            </div>
            
            <div class="card">
                <div class="flex items-center justify-between">
                    <div>
                        <p class="text-gray-600 text-sm">Total Cost</p>
                        <p class="text-3xl font-bold text-red-600" id="total-cost">-</p>
                    </div>
                    <div class="bg-red-100 p-3 rounded-full">
                        <i class="fas fa-dollar-sign text-red-500 text-xl"></i>
                    </div>
                </div>
            </div>
        </div>


        <!-- Workdir List -->
        <div id="workdir-overview" class="card">
            <div class="flex items-center justify-between mb-6">
                <h2 class="text-xl font-semibold">Working Directories</h2>
                <div class="text-sm text-gray-600">
                    Showing <span id="showing-count">0</span> of <span id="total-count">0</span> workdirs
                </div>
            </div>
            
            <div id="loading" class="text-center py-8">
                <i class="fas fa-spinner fa-spin text-2xl text-gray-400"></i>
                <p class="text-gray-600 mt-2">Loading workdir statistics...</p>
            </div>
            
            <div id="workdir-list" class="space-y-4" style="display: none;">
                <!-- Workdir cards will be inserted here -->
            </div>
            
            <div id="no-results" class="text-center py-8" style="display: none;">
                <i class="fas fa-search text-4xl text-gray-300"></i>
                <p class="text-gray-500 mt-4">No workdirs match your current filters</p>
            </div>
        </div>

        <!-- Workdir Detail View -->
        <div id="workdir-detail" class="card" style="display: none;">
            <div class="flex items-center justify-between mb-6">
                <div class="flex items-center space-x-4">
                    <button onclick="showWorkdirOverview()" class="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg transition-colors duration-200">
                        <i class="fas fa-arrow-left mr-2"></i>Back to Overview
                    </button>
                    <div>
                        <h2 class="text-xl font-semibold">Sessions in Directory</h2>
                        <p class="text-sm text-gray-600 font-mono" id="current-workdir-path"></p>
                    </div>
                </div>
                <div class="text-sm text-gray-600">
                    <span id="sessions-count">0</span> sessions (<span id="active-sessions-count">0</span> active)
                </div>
            </div>
            
            <div id="sessions-loading" class="text-center py-8">
                <i class="fas fa-spinner fa-spin text-2xl text-gray-400"></i>
                <p class="text-gray-600 mt-2">Loading sessions...</p>
            </div>
            
            <div id="sessions-list" class="space-y-4" style="display: none;">
                <!-- Session cards will be inserted here -->
            </div>
            
            <div id="no-sessions" class="text-center py-8" style="display: none;">
                <i class="fas fa-history text-4xl text-gray-300"></i>
                <p class="text-gray-500 mt-4">No sessions found for this workdir</p>
            </div>
        </div>
    </div>

    <script>
        // Global state
        let allStats = [];
        let filteredStats = [];
        let currentWorkdir = null;
        let currentSessions = [];
        let ws = null;

        // Initialize
        document.addEventListener('DOMContentLoaded', function() {
            initializeWebSocket();
            loadStats();
            setupEventListeners();
        });

        function initializeWebSocket() {
            const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
            const wsUrl = `${protocol}//${window.location.host}/ws`;
            
            ws = new WebSocket(wsUrl);
            
            ws.onopen = function() {
                updateConnectionStatus(true);
            };
            
            ws.onmessage = function(event) {
                const data = JSON.parse(event.data);
                if (data.type === 'stats_update') {
                    // Store current filter state before update
                    const currentFilters = {
                        search: document.getElementById('search-input').value,
                        status: document.getElementById('filter-status').value,
                        sort: document.getElementById('sort-by').value
                    };
                    
                    updateData(data.data);
                    
                    // Restore filter state after update
                    document.getElementById('search-input').value = currentFilters.search;
                    document.getElementById('filter-status').value = currentFilters.status;
                    document.getElementById('sort-by').value = currentFilters.sort;
                    
                    // Re-apply filters with preserved state
                    applyFilters();
                }
            };
            
            ws.onclose = function() {
                updateConnectionStatus(false);
                // Reconnect after 5 seconds
                setTimeout(initializeWebSocket, 5000);
            };
            
            ws.onerror = function() {
                updateConnectionStatus(false);
            };
        }

        function updateConnectionStatus(connected) {
            const status = document.getElementById('connection-status');
            const text = document.getElementById('connection-text');
            
            if (connected) {
                status.className = 'w-3 h-3 bg-green-400 rounded-full animate-pulse';
                text.textContent = 'Connected';
            } else {
                status.className = 'w-3 h-3 bg-red-400 rounded-full';
                text.textContent = 'Disconnected';
            }
        }

        async function loadStats() {
            try {
                showLoading(true);
                const hoursBack = document.getElementById('filter-hours').value;
                const params = hoursBack ? `?hours_back=${hoursBack}` : '';
                
                const response = await fetch(`/api/stats${params}`);
                const data = await response.json();
                
                updateData(data);
            } catch (error) {
                console.error('Error loading stats:', error);
                showError('Failed to load statistics');
            } finally {
                showLoading(false);
            }
        }

        function updateData(data) {
            allStats = data.stats || [];
            updateSummary(data);
            applyFilters();
            
            const lastUpdated = new Date(data.last_updated).toLocaleString();
            document.getElementById('last-updated').textContent = `Updated: ${lastUpdated}`;
        }

        function updateSummary(data) {
            document.getElementById('total-workdirs').textContent = (data.total_count || 0).toLocaleString();
            document.getElementById('active-workdirs').textContent = (data.active_count || 0).toLocaleString();
            document.getElementById('total-tokens').textContent = formatNumber(data.total_tokens || 0);
            document.getElementById('total-cost').textContent = `$${(data.total_cost || 0).toFixed(2)}`;
        }

        function setupEventListeners() {
            document.getElementById('search-input').addEventListener('input', applyFilters);
            document.getElementById('filter-status').addEventListener('change', applyFilters);
            document.getElementById('filter-hours').addEventListener('change', function() {
                loadStats();
            });
            document.getElementById('sort-by').addEventListener('change', applyFilters);
            document.getElementById('refresh-btn').addEventListener('click', loadStats);
        }

        function applyFilters() {
            const searchTerm = document.getElementById('search-input').value.toLowerCase();
            const statusFilter = document.getElementById('filter-status').value;
            const sortBy = document.getElementById('sort-by').value;
            
            // Filter stats
            filteredStats = allStats.filter(stat => {
                // Search filter
                if (searchTerm && !stat.workdir.toLowerCase().includes(searchTerm)) {
                    return false;
                }
                
                // Status filter
                if (statusFilter === 'active' && !stat.is_active) {
                    return false;
                }
                if (statusFilter === 'inactive' && stat.is_active) {
                    return false;
                }
                
                return true;
            });
            
            // Sort stats
            filteredStats.sort((a, b) => {
                switch (sortBy) {
                    case 'last_activity':
                        return new Date(b.last_activity || 0) - new Date(a.last_activity || 0);
                    case 'total_tokens':
                        return b.total_tokens - a.total_tokens;
                    case 'total_cost':
                        return b.total_cost - a.total_cost;
                    case 'session_count':
                        return b.session_count - a.session_count;
                    case 'workdir':
                        return a.workdir.localeCompare(b.workdir);
                    default:
                        return 0;
                }
            });
            
            renderWorkdirs();
        }

        function renderWorkdirs() {
            const container = document.getElementById('workdir-list');
            const noResults = document.getElementById('no-results');
            
            document.getElementById('showing-count').textContent = filteredStats.length.toLocaleString();
            document.getElementById('total-count').textContent = allStats.length.toLocaleString();
            
            if (filteredStats.length === 0) {
                container.style.display = 'none';
                noResults.style.display = 'block';
                return;
            }
            
            container.style.display = 'block';
            noResults.style.display = 'none';
            
            const searchTerm = document.getElementById('search-input').value.toLowerCase();
            
            container.innerHTML = filteredStats.map(stat => {
                const lastActivity = stat.last_activity ? 
                    new Date(stat.last_activity).toLocaleString() : 'Unknown';
                
                const statusClass = stat.is_active ? 'status-active' : 'status-inactive';
                const statusIcon = stat.is_active ? 'fa-play-circle' : 'fa-pause-circle';
                const statusText = stat.is_active ? 'ACTIVE' : 'INACTIVE';
                
                let workdirDisplay = stat.workdir;
                if (searchTerm) {
                    const regex = new RegExp(`(${escapeRegex(searchTerm)})`, 'gi');
                    workdirDisplay = workdirDisplay.replace(regex, '<mark class="search-highlight">$1</mark>');
                }
                
                return `
                    <div class="workdir-card border border-gray-200 rounded-lg p-4 hover:shadow-md transition-all duration-200 cursor-pointer" onclick="showWorkdirDetails('${stat.workdir.replace(/'/g, "\\'")}')">
                        <div class="flex items-start justify-between">
                            <div class="flex-1">
                                <div class="flex items-center space-x-3 mb-2">
                                    <span class="px-2 py-1 rounded-full text-xs font-medium border ${statusClass}">
                                        <i class="fas ${statusIcon} mr-1"></i><span class="${stat.is_active ? 'status-active-text' : ''}">${statusText}</span>
                                    </span>
                                    <span class="text-sm text-gray-500">${stat.session_count} sessions</span>
                                    <span class="text-sm text-gray-500">${stat.active_sessions.length} active</span>
                                </div>
                                
                                <h3 class="font-mono text-sm font-semibold text-gray-800 mb-2 break-all">
                                    ${workdirDisplay}
                                </h3>
                                
                                <div class="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm">
                                    <div>
                                        <span class="text-gray-600">Tokens:</span>
                                        <span class="font-medium">${formatNumber(stat.total_tokens)}</span>
                                    </div>
                                    <div>
                                        <span class="text-gray-600">Cost:</span>
                                        <span class="font-medium">$${stat.total_cost.toFixed(3)}</span>
                                    </div>
                                    <div>
                                        <span class="text-gray-600">Models:</span>
                                        <span class="font-medium">${stat.models_used.join(', ') || 'None'}</span>
                                    </div>
                                    <div>
                                        <span class="text-gray-600">Last Activity:</span>
                                        <span class="font-medium">${lastActivity}</span>
                                    </div>
                                </div>
                                
                                ${stat.cache_creation_tokens || stat.cache_read_tokens ? `
                                    <div class="mt-2 text-sm text-gray-600">
                                        Cache: Created ${formatNumber(stat.cache_creation_tokens)}, Read ${formatNumber(stat.cache_read_tokens)}
                                    </div>
                                ` : ''}
                            </div>
                        </div>
                    </div>
                `;
            }).join('');
        }


        function showLoading(show) {
            const loading = document.getElementById('loading');
            const workdirList = document.getElementById('workdir-list');
            
            if (show) {
                loading.style.display = 'block';
                workdirList.style.display = 'none';
            } else {
                loading.style.display = 'none';
                if (filteredStats.length > 0) {
                    workdirList.style.display = 'block';
                }
            }
        }

        function showError(message) {
            // Simple error display - could be enhanced with a toast library
            console.error(message);
        }

        function formatNumber(num) {
            if (num >= 1e9) return (num / 1e9).toFixed(1) + 'B';
            if (num >= 1e6) return (num / 1e6).toFixed(1) + 'M';
            if (num >= 1e3) return (num / 1e3).toFixed(1) + 'K';
            return num.toLocaleString();
        }

        function escapeRegex(string) {
            return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        }

        // Navigation functions
        function showWorkdirDetails(workdir) {
            currentWorkdir = workdir;
            document.getElementById('workdir-overview').style.display = 'none';
            document.getElementById('workdir-detail').style.display = 'block';
            document.getElementById('current-workdir-path').textContent = workdir;
            
            loadSessions(workdir);
        }

        function showWorkdirOverview() {
            currentWorkdir = null;
            document.getElementById('workdir-detail').style.display = 'none';
            document.getElementById('workdir-overview').style.display = 'block';
        }

        async function loadSessions(workdir) {
            try {
                showSessionsLoading(true);
                
                const encodedWorkdir = encodeURIComponent(workdir);
                const response = await fetch(`/api/workdir/${encodedWorkdir}/sessions`);
                const data = await response.json();
                
                currentSessions = data.sessions || [];
                renderSessions();
                
                document.getElementById('sessions-count').textContent = data.total_sessions || 0;
                document.getElementById('active-sessions-count').textContent = data.active_sessions || 0;
                
            } catch (error) {
                console.error('Error loading sessions:', error);
                showError('Failed to load sessions');
            } finally {
                showSessionsLoading(false);
            }
        }

        function renderSessions() {
            const container = document.getElementById('sessions-list');
            const noSessions = document.getElementById('no-sessions');
            
            if (currentSessions.length === 0) {
                container.style.display = 'none';
                noSessions.style.display = 'block';
                return;
            }
            
            container.style.display = 'block';
            noSessions.style.display = 'none';
            
            container.innerHTML = currentSessions.map(session => {
                const startTime = session.start_time ? 
                    new Date(session.start_time).toLocaleString() : 'Unknown';
                const endTime = session.end_time ? 
                    new Date(session.end_time).toLocaleString() : 'Ongoing';
                
                const statusClass = session.is_active ? 'status-active' : 'status-inactive';
                const statusIcon = session.is_active ? 'fa-play-circle' : 'fa-pause-circle';
                const statusText = session.is_active ? 'ACTIVE' : 'INACTIVE';
                
                return `
                    <div class="border border-gray-200 rounded-lg p-4">
                        <div class="flex items-start justify-between mb-4">
                            <div class="flex items-center space-x-3">
                                <span class="px-2 py-1 rounded-full text-xs font-medium border ${statusClass}">
                                    <i class="fas ${statusIcon} mr-1"></i><span class="${session.is_active ? 'status-active-text' : ''}">${statusText}</span>
                                </span>
                                <span class="font-mono text-sm text-gray-600">${session.session_id}</span>
                            </div>
                            <div class="text-sm text-gray-500">
                                $${session.total_cost.toFixed(3)}
                            </div>
                        </div>
                        
                        <div class="mb-4">
                            <h4 class="font-semibold text-gray-800 mb-2">Session Abstract</h4>
                            <p class="text-gray-700 bg-gray-50 p-3 rounded-lg italic">
                                "${session.abstract || 'No description available'}"
                            </p>
                        </div>
                        
                        <div class="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm mb-4">
                            <div>
                                <span class="text-gray-600">Tokens:</span>
                                <span class="font-medium">${formatNumber(session.total_tokens)}</span>
                            </div>
                            <div>
                                <span class="text-gray-600">Input/Output:</span>
                                <span class="font-medium">${formatNumber(session.input_tokens)}/${formatNumber(session.output_tokens)}</span>
                            </div>
                            <div>
                                <span class="text-gray-600">Models:</span>
                                <span class="font-medium">${session.models_used.join(', ') || 'None'}</span>
                            </div>
                            <div>
                                <span class="text-gray-600">Duration:</span>
                                <span class="font-medium">${startTime} - ${endTime}</span>
                            </div>
                        </div>
                        
                        ${session.cache_creation_tokens || session.cache_read_tokens ? `
                            <div class="text-sm text-gray-600 border-t pt-2">
                                Cache: Created ${formatNumber(session.cache_creation_tokens)}, Read ${formatNumber(session.cache_read_tokens)}
                            </div>
                        ` : ''}
                        
                        ${session.first_user_prompt ? `
                            <details class="mt-4">
                                <summary class="cursor-pointer text-sm text-blue-600 hover:text-blue-800">
                                    <i class="fas fa-eye mr-1"></i>View First Prompt
                                </summary>
                                <div class="mt-2 p-3 bg-blue-50 rounded-lg text-sm text-gray-700 max-h-32 overflow-y-auto">
                                    ${session.first_user_prompt.replace(/\n/g, '<br>')}
                                </div>
                            </details>
                        ` : ''}
                    </div>
                `;
            }).join('');
        }

        function showSessionsLoading(show) {
            const loading = document.getElementById('sessions-loading');
            const sessionsList = document.getElementById('sessions-list');
            
            if (show) {
                loading.style.display = 'block';
                sessionsList.style.display = 'none';
            } else {
                loading.style.display = 'none';
                if (currentSessions.length > 0) {
                    sessionsList.style.display = 'block';
                }
            }
        }
    </script>
</body>
</html>